#ifndef AUTODRIVE_ALGORITHM_STRUCTURE_ID_GENERATOR_H_
#define AUTODRIVE_ALGORITHM_STRUCTURE_ID_GENERATOR_H_

#include <cstdint>
#include <deque>
#include <array>
#include <mutex>



class IdGenerator {
 public:
  IdGenerator() noexcept;
  ~IdGenerator() noexcept = default;
  IdGenerator(IdGenerator const&) = default;
  IdGenerator& operator=(IdGenerator const&) = default;
  IdGenerator(IdGenerator&&) = default;
  IdGenerator& operator=(IdGenerator&&) = default;

  /// @brief Initialize
  void Init() noexcept;

  /// @brief Get id
  ///
  /// @throw OutOfResourceException  when no id available
  ///
  /// @return smallest available id
  std::uint8_t GetId() noexcept(false);

  /// @brief Get whether id is used
  ///
  /// @return is_id_used_[id]
  bool IsIdUsed(std::uint8_t id) const noexcept;

  /// @brief Release id
  ///
  /// @param id  id
  void ReleaseId(std::uint8_t id) noexcept;

 private:
  /// @brief Max id
  static constexpr std::uint16_t kMaxId{256U};
  /// @brief Task queue
  std::deque<std::uint8_t> id_queue_;
  /// @brief Whether one id is used
  std::array<bool, kMaxId> is_id_used_;
  /// @brief Mutex
  std::mutex mutex_;
};



#endif // AUTODRIVE_ALGORITHM_STRUCTURE_ID_GENERATOR_H_

/* vim: set ts=2 sw=2 sts=2 tw=100 et: */
